package redis.clients.jedis.script;

/**
 * @Description
 * @Author why
 * @Version 1.0.0
 * @Since 1.0
 * @Date 2022/8/8
 */
public interface LockScript {

    /**
     * 获取锁 成功返回1
     */
    String lualock = "local key = KEYS[1]\n" +
            "local content = ARGV[1]\n" +
            "local ttl = tonumber(ARGV[2])\n" +
            "local lockSet = redis.call('setnx', key, content)\n" +
            "if lockSet == 1 then\n" +
            "    redis.call('EXPIRE', key, ttl)\n" +
            "else\n" +
            "    local value = redis.call('get', key)\n" +
            "    if(value == content) then\n" +
            "        lockSet = 1\n" +
            "        redis.call('EXPIRE', key, ttl)\n" +
            "    end\n" +
            "end\n" +
            "return lockSet";


    /**
     * 释放锁 成功返回1
     */
    String luaUnlock = "local key = KEYS[1]\n" +
            "local content = ARGV[1]\n" +
            "local value = redis.call('get', key)\n" +
            "if value == content then\n" +
            "return redis.call('del', key)\n" +
            "else\n" +
            "return 0\n" +
            "end";

    String luaReentrantLock = "local key = KEYS[1]\n" +
            "local threadId = ARGV[1]\n" +
            "local releaseTime = ARGV[2]\n" +
            "if(redis.call('exists', key) == 0) then \n" +
            "    redis.call('hset', key, threadId, '1')\n" +
            "    redis.call('expire', key, releaseTime)\n" +
            "    return 1\n" +
            "end\n" +
            "if(redis.call('hexists', key, threadId) == 1) then\n" +
            "    redis.call('hincrby', key, threadId, '1')\n" +
            "    redis.call('expire', key, releaseTime)\n" +
            "    return 1\n" +
            "end\n" +
            "return 0";

    String unlockReentrantLock = "local key = KEYS[1]\n" +
            "local threadId = ARGV[1]\n" +
            "local releaseTime = ARGV[2]\n" +
            "\n" +
            "if (redis.call('HEXISTS', key, threadId) == 0) then\n" +
            "    return nil\n" +
            "end\n" +
            "local count = redis.call('HINCRBY', key, threadId, -1)\n" +
            "\n" +
            "if (count > 0) then\n" +
            "    redis.call('EXPIRE', key, releaseTime)\n" +
            "    return nil\n" +
            "else\n" +
            "    redis.call('DEL', key)\n" +
            "    return nil\n" +
            "end";
}
